#ifndef MAIN_C3LOG_H_
#define MAIN_C3LOG_H_
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <cstring>
#include <chrono>

#ifndef LOG_TAG
#define LOG_TAG "common"
#endif
void log_tag(const char *Color, const char *TAG, const char *ModuleTAG, const char *format, ...);
void log2file(const char *log_path, bool append, bool ts, const char *format, ...);

#define LOGD(...)                  \
    {                              \
        log_tag("\033[0;36m", "D", LOG_TAG, __VA_ARGS__); \
    }
#define LOGI(...)                  \
    {                              \
        log_tag("\033[0;32m", "I", LOG_TAG, __VA_ARGS__); \
    }
#define LOGW(...)                  \
    {                              \
        log_tag("\033[0;33m", "W", LOG_TAG, __VA_ARGS__); \
    }
#define LOGE(...)                  \
    {                              \
        log_tag("\033[0;31m", "E", LOG_TAG, __VA_ARGS__); \
    }

void read_status(const char *log_path, char *buf, int size);
void print_file(const char *log_path);
int init_log();
int dump_log();
double get_sys_secend();

class CustomLog{
 public:
    FILE *mpLogFD = nullptr;
    char mpLogName[32];
    size_t mLogSize = 0;
    int mNameId = 0;
    int mContentId = 0;
    bool mInited = false;

    static int createNewLogFile(int history_id, int cur_name_id);
};


#define TRACE_B(...) \
    Trace trace; \
    trace.begin(LOG_TAG, __func__, ##__VA_ARGS__);

class Trace{
 public:
    bool mLogOn = true;
    char mTag[48]={0};
    Trace() {
    }

    ~Trace() {
        if (mLogOn) {
            log_tag("\033[0;32m", "I", "", "[T_END] %s X", mTag);
        }
    }

    bool begin(const char *logtagstr, const char *func_name) {
        return begin(logtagstr, func_name, "");
    }

    bool begin(const char *logtagstr, const char *func_name, const char *format, ...){
        if (mLogOn) {
            va_list args;
            va_start(args, format);
            int len = snprintf(mTag, sizeof(mTag), "%s %s() ", logtagstr, func_name);
            vsnprintf(mTag + len, sizeof(mTag) - len, format, args);
            va_end(args);
            log_tag("\033[0;32m", "I", "", "[T_BEG] %s E", mTag);
        } else {
            return false;
        }

        return true;
    }
};

class PerfTrace{
 public:
    std::chrono::steady_clock::time_point mcur_clock;
    std::chrono::steady_clock::duration mspan;
    PerfTrace() {
        mcur_clock = std::chrono::steady_clock::now();
    }

    ~PerfTrace() {
        mspan = mcur_clock - std::chrono::steady_clock::now();
        auto time_s = double(mspan.count()) * std::chrono::steady_clock::period::num /
            std::chrono::steady_clock::period::den;
        log_tag("\033[0;32m", "I", "", "[T_END] time_s:%llfs X", time_s);
    }
};

#endif  // MAIN_C3LOG_H_
